package io.github.mayubao.kotlintest

import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Test
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock

/**
 * test inline
 * 1.what is inline
 *  when we call a method, in compile time, the compilor use method frame push to the method stack, if the method be called many times, it push the stack many times.
 *  and the inline keyword that modify the method translate the code, not method. It is the big difference between inline method and non-inline meothod
 *  the  inline symbol
 * 2.how the inline do something
 *  add the symbol "inline" before the method name， can make the method is an inline method
 *
 * 3.benefit of the inline
 *  Inline method will increse codes, but just in compile time. And it reduces the time like push method frame into method stack.
 */
class Day19_InLineTest{

    var lock = ReentrantLock();

    @Test
    fun testGeneralMethod(){
        val startTime = System.currentTimeMillis()
        for(i in 1..1000000){
            check(lock, {
                "I am the general method"
            })
        }
        val endTime = System.currentTimeMillis()
        println("testGeneralMethod consume time is ${endTime - startTime}" )
        assertEquals("test", "test")
    }


    @Test
    fun testInlineMethod(){
        val startTime = System.currentTimeMillis()
        for(i in 1..1000000){
            checkInline(lock, {
                "I am the inline method"
            })
        }
        val endTime = System.currentTimeMillis()
        println("testInlineMethod consume time is ${endTime - startTime}" )
        assertEquals("test", "test")
    }


    fun <T> check(lock: Lock, body: () -> T): T {
        lock.lock()
        try {
            return body()
        } finally {
            lock.unlock()
        }
    }

    inline fun <T> checkInline(lock: Lock, body: () -> T): T {
        lock.lock()
        try {
            return body()
        } finally {
            lock.unlock()
        }
    }


    //Summray:
    //the inline method is faster than general method

    //the log result as follow:
//    testGeneralMethod consume time is 9
//    testInlineMethod consume time is 0

}